home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
clang
/
cslib15b.zip
/
DEMO
/
ADDRESS
/
CSADDIO.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-20
|
20KB
|
656 lines
#include "csaddio.h"
extern unsigned _stklen=7000; //A large stack is needed
////////////// The used .def file is included as comment ////////
/*
class: NAM_foundation
record: record
file: csadr.dbf
field: name s 40 T
field: adre s 32
field: city s 23 Y
field: count s 32
field: zip s 9
field: tel s 17
field: update d MDY2
field: birth d DMY4 Y
field: relation s 10 Y
field: info s 70
*/
/////////////// End of .def file //////////////////////////////////////////////
///////////////////////////////// Constructor ////////////////////////////////
NAM_foundation::NAM_foundation(void)
{
is_open=FALSE;
current=1;
_update.format(MDY2);
_birth.format(DMY4);
}
///////////////////////////////// reindex ////////////////////////////////////
void NAM_foundation::reindex(void)
{
U32 l=current;
record *rp;
in1.empty();
in2.empty();
in3.empty();
in4.empty();
for(current=numrec(); current>0; current--)
{
rp=(record *)db.locate_rec(current);
tokenize(rp->_name,&NAM_foundation::in1_ins_tok);
in2.insert(rp->_city,¤t);
in3.insert(&rp->__birth,¤t);
in4.insert(rp->_relation,¤t);
}
current=l;
}
/////////////// append blank//////////////////////////////////////
void NAM_foundation::append_blank(void)
{
append();
tokenize(recp->_name,&NAM_foundation::in1_ins_tok);
in2.insert(rec._city,¤t);
in3.insert(&rec.__birth,¤t);
in4.insert(rec._relation,¤t);
}
///////////////////////////////// append /////////////////////////////////////
// This function doesn't update the indexes, which can save some
// disk I/O because you are likely to alter the fields
// immediatly after you have appended the record.
// However, if you have an index on a field you don't update, this
// record will NOT appear in that particularly index!
// The 'append_blank' function does update all indexes, which
// makes it a safer, but slower option.
//
void NAM_foundation::append(void)
{
write_rec();
memset(&rec,0,sizeof(record));
current=db.append_rec(&rec);
recp=(record *)db.locate_rec(current);
dirty=TRUE;
_update.sem_jul(0L);
_birth.sem_jul(0L);
}
///////////////////////////////// open ///////////////////////////////////////
void NAM_foundation::open(void)
{
if(is_open) return;
int needs_reindex=FALSE;
dirty=FALSE;
#ifdef _Windows
int fre=300/9; //Use 300 kB for buffers. You may increase this.
#else
int fre=(int)(coreleft()-100000L)/9/1024;
fre=max(fre,0);
#endif
if(!db.open("csadr.dbf",fre))
{
csmess_disp("FATAL: Can't open database csadr.dbf.");
exit(1);
}
if(db.lengthrec()!=sizeof(record))
{
csmess_disp("FATAL: wrong record size.\n\rProbably wrong or old database file.");
db.close();
exit(1);
}
if(!file_exist("csadr01.idx"))
{
in1.multiple_keys(TRUE);
in1.define("csadr01.idx",NAME_LENGTH+1,sizeof(long));
needs_reindex=TRUE;
}
in1.open("csadr01.idx",fre*2);
if(!file_exist("csadr02.idx"))
{
in2.multiple_keys(TRUE);
in2.define("csadr02.idx",CITY_LENGTH+1,sizeof(long));
needs_reindex=TRUE;
}
in2.open("csadr02.idx",fre*2);
if(!file_exist("csadr03.idx"))
{
in3.multiple_keys(TRUE);
in3.define("csadr03.idx",sizeof(long),sizeof(long));
needs_reindex=TRUE;
}
in3.open("csadr03.idx",fre*2);
if(!file_exist("csadr04.idx"))
{
in4.multiple_keys(TRUE);
in4.define("csadr04.idx",RELATION_LENGTH+1,sizeof(long));
needs_reindex=TRUE;
}
in4.open("csadr04.idx",fre*2);
if(needs_reindex) reindex();
is_open=TRUE;
if(numrec()==0) append_blank();
else read_rec();
order(UNSORTED);
}
///////////////////////////////// close //////////////////////////////////////
void NAM_foundation::close(void)
{
if(!is_open) return;
write_rec();
db.close();
in1.close();
in2.close();
in3.close();
in4.close();
is_open=FALSE;
}
///////////////////////////////// define /////////////////////////////////////
void NAM_foundation::define(void)
{
db.define("csadr.dbf",sizeof(record));
in1.multiple_keys(TRUE);
in1.define("csadr01.idx",NAME_LENGTH+1,sizeof(long));
in2.multiple_keys(TRUE);
in2.define("csadr02.idx",CITY_LENGTH+1,sizeof(long));
in3.multiple_keys(TRUE);
in3.define("csadr03.idx",sizeof(long),sizeof(long));
in4.multiple_keys(TRUE);
in4.define("csadr04.idx",RELATION_LENGTH+1,sizeof(long));
}
///////////////////////////////// pack ///////////////////////////////////////
void NAM_foundation::pack(void)
{
write_rec();
db.pack();
reindex();
if(numrec()==0) append_blank();
top();
}
///////////////////////////////// skip ///////////////////////////////////////
int NAM_foundation::skip(int delta)
{
long tmp_curr=curr_rec();
write_rec();
(this->*skip_fun)(delta);
read_rec();
return (int)(curr_rec()-tmp_curr);
}
///////////////////////////////// order //////////////////////////////////////
void NAM_foundation::order(int nr)
{
switch(nr)
{
case 0: //Unsorted
skip_fun =&NAM_foundation::skip0;
top_fun =&NAM_foundation::top0;
bottom_fun=&NAM_foundation::bottom0;
search_fun=&NAM_foundation::search0;
break;
case 1: //Index on field name
skip_fun =&NAM_foundation::skip1;
top_fun =&NAM_foundation::top1;
bottom_fun=&NAM_foundation::bottom1;
search_fun=&NAM_foundation::search1;
break;
case 2: //Index on field city
skip_fun =&NAM_foundation::skip2;
top_fun =&NAM_foundation::top2;
bottom_fun=&NAM_foundation::bottom2;
search_fun=&NAM_foundation::search2;
break;
case 3: //Index on field birth
skip_fun =&NAM_foundation::skip3;
top_fun =&NAM_foundation::top3;
bottom_fun=&NAM_foundation::bottom3;
search_fun=&NAM_foundation::search3;
break;
case 4: //Index on field relation
skip_fun =&NAM_foundation::skip4;
top_fun =&NAM_foundation::top4;
bottom_fun=&NAM_foundation::bottom4;
search_fun=&NAM_foundation::search4;
break;
}
top();
}
/////////////////////////////writing record ///////////////////////////////
void NAM_foundation::write_rec2(void)
{
if(strcmp(recp->_name,rec._name))
{
tokenize(recp->_name,&NAM_foundation::in1_del_tok);
tokenize(rec._name,&NAM_foundation::in1_ins_tok);
}
if(strcmp(recp->_city,rec._city))
{
in2.delet(recp->_city,¤t);
in2.insert(rec._city,¤t);
}
rec.__update=_update.sem_jul();
rec.__birth=_birth.sem_jul();
if(recp->__birth!=rec.__birth)
{
in3.delet(&recp->__birth,¤t);
in3.insert(&rec.__birth,¤t);
}
if(strcmp(recp->_relation,rec._relation))
{
in4.delet(recp->_relation,¤t);
in4.insert(rec._relation,¤t);
}
db.write_rec(current,&rec);
dirty=FALSE;
}
///////////////////////////////// export /////////////////////////////////////
int NAM_foundation::export(char *s)
{
FILE *fo=fopen(s,"w");
if(fo==NULL) return FALSE;
write_rec();
fprintf(fo,"class: NAM_foundation");
fprintf(fo,"\nrecord: record");
fprintf(fo,"\nfile: csadr.dbf");
fprintf(fo,"\nfield: name s 40 Y");
fprintf(fo,"\nfield: adre s 32 ");
fprintf(fo,"\nfield: city s 23 Y");
fprintf(fo,"\nfield: count s 32 ");
fprintf(fo,"\nfield: zip s 9 ");
fprintf(fo,"\nfield: tel s 17 ");
fprintf(fo,"\nfield: update d ");
fprintf(fo,"\nfield: birth d Y");
fprintf(fo,"\nfield: relation s 10 Y");
fprintf(fo,"\nfield: info s 70 ");
if(ferror(fo)) { fclose(fo); return FALSE; }
record *recp;
DATE conv;
conv.format(Y4MD);
for(long l=numrec();l>0;l--)
{
recp=( record * )db.locate_rec(l);
fprintf(fo,"\n%c",12);
fprintf(fo,"\n%s",recp->_name);
fprintf(fo,"\n%s",recp->_adre);
fprintf(fo,"\n%s",recp->_city);
fprintf(fo,"\n%s",recp->_count);
fprintf(fo,"\n%s",recp->_zip);
fprintf(fo,"\n%s",recp->_tel);
conv.sem_jul(recp->__update);
fprintf(fo,"\n%s",(char *)conv);
conv.sem_jul(recp->__birth);
fprintf(fo,"\n%s",(char *)conv);
fprintf(fo,"\n%s",recp->_relation);
fprintf(fo,"\n%s",recp->_info);
fprintf(fo,"\n"); //Additional linefeed, to avoid trouble!
if(ferror(fo)) { fclose(fo); return FALSE; }
}
return !fclose(fo);
}
///////////////////////////////// import /////////////////////////////////////
int NAM_foundation::import(char *s)
{
FILE *fr=fopen(s,"r");
if(fr==NULL) return FALSE;
#define MAX_NUM_FIELDS 100 //Increase this to allow more fields
#define MAX_FIELD_LEN 500 //Increase this to allow longer fields
int *finu;
finu=(int *)malloc(MAX_NUM_FIELDS*sizeof(int));
if(finu==NULL) { fclose(fr); return FALSE; }
char *fibu;
fibu=(char *)malloc(MAX_FIELD_LEN);
if(fibu==NULL) { fclose(fr); free(finu); return FALSE; }
*fibu=0;
char *fipo=fibu+strlen("field:");
char *cp;
int ifieldnr=0;
int ofieldnr;
DATE conv;
conv.format(Y4MD);
memset(finu,0,MAX_NUM_FIELDS*sizeof(int));
fgets(fibu,MAX_FIELD_LEN,fr);
while(!strchr(fibu,12))
{
strlwr(fibu);
notabs(fibu);
trim_string(fibu);
if(strstr(fibu,"field:"))
{
ifieldnr++;
trim_string(fipo);
if((cp=strchr(fipo,' '))!=NULL) *cp=0;
if (!strcmp(fipo,"name")) ofieldnr=1;
else if(!strcmp(fipo,"adre")) ofieldnr=2;
else if(!strcmp(fipo,"city")) ofieldnr=3;
else if(!strcmp(fipo,"count")) ofieldnr=4;
else if(!strcmp(fipo,"zip")) ofieldnr=5;
else if(!strcmp(fipo,"tel")) ofieldnr=6;
else if(!strcmp(fipo,"update")) ofieldnr=7;
else if(!strcmp(fipo,"birth")) ofieldnr=8;
else if(!strcmp(fipo,"relation")) ofieldnr=9;
else if(!strcmp(fipo,"info")) ofieldnr=10;
else ofieldnr=0;
finu[ifieldnr]=ofieldnr;
}
fgets(fibu,MAX_FIELD_LEN,fr);
}
for(;;)
{
if(!strchr(fibu,12))
{
ifieldnr++;
if(ifieldnr<MAX_NUM_FIELDS)
switch(finu[ifieldnr])
{
case 0: break;
case 1:
fibu[NAME_LENGTH]=0;
name(fibu);
break;
case 2:
fibu[ADRE_LENGTH]=0;
adre(fibu);
break;
case 3:
fibu[CITY_LENGTH]=0;
city(fibu);
break;
case 4:
fibu[COUNT_LENGTH]=0;
count(fibu);
break;
case 5:
fibu[ZIP_LENGTH]=0;
zip(fibu);
break;
case 6:
fibu[TEL_LENGTH]=0;
tel(fibu);
break;
case 7:
conv=fibu;
_update.sem_jul(conv.sem_jul());
break;
case 8:
conv=fibu;
_birth.sem_jul(conv.sem_jul());
break;
case 9:
fibu[RELATION_LENGTH]=0;
relation(fibu);
break;
case 10:
fibu[INFO_LENGTH]=0;
info(fibu);
break;
}
}
else
{
ifieldnr=0;
append_blank();
}
if(feof(fr)) break;
fgets(fibu,MAX_FIELD_LEN,fr);
cp=fibu+(max(1,strlen(fibu))-1);
if(*cp=='\n') *cp=0; //removing the line feed
}
fclose(fr);
free(fibu);
free(finu);
#undef MAX_NUM_FIELDS
#undef MAX_FIELD_LEN
return TRUE;
}
///////////////////////////////// export to dBASE compatible file. ///////////
int NAM_foundation::to_DBASE(char *s)
{
char bufje[12];
if(!is_open) return FALSE;
write_rec();
FILE *fo=fopen(s,"wb");
if(fo==NULL) return FALSE;
int i;
DATE d_upda;
d_upda.sem_jul(db.sj_updated());
fputc(03,fo);
fputc(d_upda.year()%100,fo);
fputc(d_upda.month(),fo);
fputc(d_upda.day(),fo);
long nr_record=numrec();
fwrite(&nr_record,sizeof(long),1,fo);
putw(354,fo); //Header length
putw(250,fo); //Length of data record
for(i=0;i<20;i++) fputc(0,fo); // 20 dummy bytes
// Writing definition of field name to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"NAME");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(40,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field adre to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"ADRE");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(32,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field city to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"CITY");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(23,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field count to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"COUNT");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(32,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field zip to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"ZIP");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(9,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field tel to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"TEL");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(17,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field update to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"UPDATE");
fwrite(bufje,11,1,fo);
fputc('D',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(8,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field birth to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"BIRTH");
fwrite(bufje,11,1,fo);
fputc('D',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(8,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field relation to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"RELATION");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(10,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field info to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"INFO");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(70,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
fputc(13,fo); //Field terminator
fputc(0,fo);
// By now we have written the definition of the file structure
// to the file header.
// From here on we will export the records.
record *recp;
for(long l=numrec();l>0;l--)
{
if(ferror(fo)) { fclose(fo); return FALSE; }
recp=(record *)db.locate_rec(l);
if(db.is_delet(l)) fputc(42,fo);
else fputc(32,fo);
/////////////////////// writing field name /////////////
fprintf(fo,"%-40s",recp->_name);
/////////////////////// writing field adre /////////////
fprintf(fo,"%-32s",recp->_adre);
/////////////////////// writing field city /////////////
fprintf(fo,"%-23s",recp->_city);
/////////////////////// writing field count /////////////
fprintf(fo,"%-32s",recp->_count);
/////////////////////// writing field zip /////////////
fprintf(fo,"%-9s",recp->_zip);
/////////////////////// writing field tel /////////////
fprintf(fo,"%-17s",recp->_tel);
/////////////////////// writing field update /////////////
if(recp->__update)
{
d_upda.sem_jul(recp->__update);
fprintf(fo,"%4d",d_upda.year4());
fprintf(fo,"%02d",d_upda.month());
fprintf(fo,"%02d",d_upda.day());
}
else
{
fprintf(fo," ");
}
/////////////////////// writing field birth /////////////
if(recp->__birth)
{
d_upda.sem_jul(recp->__birth);
fprintf(fo,"%4d",d_upda.year4());
fprintf(fo,"%02d",d_upda.month());
fprintf(fo,"%02d",d_upda.day());
}
else
{
fprintf(fo," ");
}
/////////////////////// writing field relation /////////////
fprintf(fo,"%-10s",recp->_relation);
/////////////////////// writing field info /////////////
fprintf(fo,"%-70s",recp->_info);
}
fputc(26,fo); //End of File
fclose(fo);
return TRUE;
}
///////////////////////////////// tokenize field ///////////////////////
void NAM_foundation::tokenize(char *s,void(NAM_foundation::*fun)(void *))
{
char delim[]="\t,() "; //Token delimiters
char *p,*q=s;
char c;
int insert=FALSE;
const min_len=4; //Minimum length for a token to be indexed.
p=strpbrk(q,delim);
while(p)
{
c=*p; *p=0;
if(strlen(q)>=min_len) { (this->*fun)(q); insert=TRUE; }
*p=c;
do{ p=strpbrk(q=p+1,delim); }while(q==p);
}
if(strlen(q)>=min_len) { (this->*fun)(q); insert=TRUE; }
if(!insert) (this->*fun)(s);
}